﻿using WubiMaster.ViewModels;

namespace WubiMaster;

public partial class App : Application
{
    private static ViewModelLocator? locator;
    private Mutex? mutex;
    public static bool IsMaximized { get; set; }
    public static ViewModelLocator? Locator => locator ??= App.Current.FindResource("Locator") as ViewModelLocator;

    private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        try
        {
            e.Handled = true;
            LogHelper.Fatal(e.Exception.Message);
        }
        catch (Exception ex)
        {
            LogHelper.Fatal("程序发生致命错误，将终止，请联系开发人员！" + ex.Message);
            this.ShowMessage("程序发生致命错误，将终止，请联系开发人员！", DialogType.Error);
            Environment.Exit(0);
        }
    }

    private void Application_Exit(object sender, ExitEventArgs e)
    {
        LogHelper.Info("程序退出");
    }

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        if (mutex != null) return;
        mutex = new Mutex(true, "WubiMaster", out bool ret);
        if (!ret)
        {
            LogHelper.Info("禁止启用多个进程");
            Environment.Exit(0);
            return;
        }

        LogHelper.Info("程序启动");

        this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
        TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
    }

    private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        StringBuilder sbEx = new();
        if (e.IsTerminating)
        {
            sbEx.Append("程序发生致命错误，将终止，请联系开发人员！\n");
        }

        if (e.ExceptionObject is Exception ex)
        {
            sbEx.Append(ex.Message);
        }
        else
        {
            sbEx.Append(e.ExceptionObject);
        }
        this.ShowMessage(sbEx.ToString(), DialogType.Error);
    }

    private void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
    {
        LogHelper.Fatal(e.Exception.Message);
        e.SetObserved();
        this.ShowMessage(e.Exception.Message, DialogType.Error);
    }
}